package com.devicestatus.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.devicestatus.constants.Constants;
import com.devicestatus.dao.DeviceDao;
import com.devicestatus.dao.DeviceOnlineRecordDao;
import com.devicestatus.dao.ProductDao;
import com.devicestatus.entity.Device;
import com.devicestatus.entity.DeviceOnlineRecord;
import com.devicestatus.entity.Product;
import com.devicestatus.service.GizwitsService;
import com.devicestatus.tools.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author MeowParse
 * @date 2017/8/14.
 */
@Service
public class GizwitsServiceImpl implements GizwitsService {

	private static final Logger logger = LoggerFactory.getLogger(GizwitsServiceImpl.class);

	@Autowired
	private DeviceDao deviceDao;
	@Autowired
	private ProductDao productDao;
	@Autowired
	private DeviceOnlineRecordDao deviceOnlineRecordDao;
	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	public void getDeviceStatus(){
		String token ;
		logger.info("getDeviceStatus");
		List<Product> products = productDao.getProductIds();
		logger.info("getProductsNum:{}", products.size());
		for(Product product : products){
			String productId = product.getId();
			logger.info("getProductId:{}",productId);
			logger.info("getProductSecret:{}", product.getSecretKey());
			if(stringRedisTemplate.hasKey(Constants.ACCESS_TOKEN+productId)){
				token = stringRedisTemplate.opsForValue().get(Constants.ACCESS_TOKEN+productId);
			}else{
				token = getAccessToken(productId, product.getSecretKey());
			}
//			if(redis.exists(Constants.ACCESS_TOKEN+productId)){//原来的代码
//				token = redis.get(Constants.ACCESS_TOKEN+productId);
//			}else{
//				token = getAccessToken(productId, product.getSecretKey());
//			}
			logger.info("getProductToken:{}",token);
			getDevicesDetail(productId,token);
		}

		logger.info("end");
	}

	public String getAccessToken(String productKey,String productSecret){
		String jsonStr = JSON.toJSONString(Constants.ACCESSJSON,true);
		JSONObject json = JSON.parseObject(jsonStr);
		json.put(Constants.PRODUCT_SECRET,productSecret);
		String result = HttpClient.sendJson(Constants.URL_PRODUCT+productKey+Constants.URL_ACCESSTOKEN,
				json.toJSONString(),null);
		JSONObject resultJson = JSON.parseObject(result);
		if(resultJson.containsKey(Constants.TOKEN)){
			stringRedisTemplate.opsForValue().set(Constants.ACCESS_TOKEN+productKey,resultJson.getString(Constants.TOKEN));
			return resultJson.getString(Constants.TOKEN);
		}
		logger.info("getAccessToken:{} pId:{},pSc", result, productKey, productSecret);
		return null;
	}

	private void getDevicesDetail(String productId, String token){
		logger.info("getDevicesDetail");
		List<String> macs = deviceDao.getMacs(productId);
		logger.info("getDevicesNum:{}",macs.size());
		for(String mac : macs){
			getDeviceDetail(productId,mac,token,0);
		}
	}

	public void getDeviceDetail(String productId,String mac,String token,int i){
		if(i > 2){
			return;
		}
		Map<String ,String> propertys= new HashMap<String, String>(){{
			put("Authorization", String.format("token %s", token));
		}};

		String result = HttpClient.sendGet(Constants.URL_PRODUCT+productId+Constants.URL_DEVICEDETAIL,
				"mac="+mac,
				propertys);

		JSONObject resultJson = JSON.parseObject(result);
		String deviceId = resultJson.getString(Constants.PRODUCT_KEY) + "/" + mac;

		if(resultJson.containsKey(Constants.IS_ONLINE)){
			boolean isOnline = resultJson.getBoolean(Constants.IS_ONLINE);
			int online = 0;
			if(isOnline){
				online = 1;
			}
			Device device = deviceDao.findOne(deviceId);

			if(device == null){
				return;
			}

			if(device.getOnline() != online){
				device.setOnline(online);
				deviceDao.save(device);
				logger.info("DeviceOnlineStatusChanged:{} =====>now:{}",deviceId,online);
				DeviceOnlineRecord deviceOnlineRecord = new DeviceOnlineRecord(deviceId,online);
				deviceOnlineRecordDao.save(deviceOnlineRecord);
			}

		}else if(resultJson.containsKey(Constants.ERROR_CODE)){//token 过期,其他情况不再请求
			String errorCode = resultJson.getString(Constants.ERROR_CODE);
			logger.info("mac:{},deviceId:{},getDeviceDetailError:{},",mac,deviceId,resultJson.toJSONString());
			if(errorCode.equals(Constants.CODE_5011)){
				String productSecret = productDao.getProductSecret(productId);
				String accessToken = getAccessToken(productId, productSecret);
				getDeviceDetail(productId,mac,accessToken,++i);
			}else if(errorCode.equals(Constants.CODE_5301)){//将机智云中不存在的设备修改为离线
				deviceDao.updateOnline(0,deviceId);
			}
		}
	}
}
